//
//  ParserToTCL.java
//  TopoManipApplet
//
//  Created by Thibaud PIQUET on 23/03/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

package src.convertisseur;
import java.util.*;
import java.io.*;
import java.lang.*;
import org.jdom.*;
import javax.swing.*;
import java.math.BigInteger;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.xml.sax.SAXException;
import java.net.*;

/**
 *
 * @author Thibaud PIQUET
 */
public class ParserToTCL implements Runnable {
	
    File ftp; // File to parse
	File fileOut; // File to create
	Writer fw; // File Writer
    BufferedWriter bw; // Buffer Writer
    String line;
    String chaine;
    String[] res;
	
    public ParserToTCL(File file, File fileOUT) throws IOException {
        this.ftp = file;
		this.fileOut = fileOUT;
        this.fw = new FileWriter(this.fileOut);
        this.bw = new BufferedWriter(this.fw);
    }
	
	public void run() {
		try {
			this.parseToTCL();
		}
		catch (Exception e) {
			e.printStackTrace();
			Resume result = Resume.getInstance();
			result.add("ParserToTCL","procedure run had some problems : "+e);
		}
	}

	public void parseToTCL() throws IOException {
		
		Element domain;
		Element information;
		Element topology;
		Element igp;
		Element nodes;
		Element links;
		Element igpLinks;
		
		Resume result = Resume.getInstance();

		try {
			
			// ******************************************************
			// Default values for TCL if there aren't in the XML file
			// bandwidth : 1Mb
			// queue : DropTail
			// delay : 10ms
			// linkType<Type1> : duplex-link
			// ******************************************************
			
			/************************************************************ Loading default values *************************************************************/
			InputStream inDefaultValues = getClass().getResourceAsStream("/resources/configuration.xml");
			
			org.jdom.input.SAXBuilder builderConfig = new org.jdom.input.SAXBuilder();
            builderConfig.setIgnoringElementContentWhitespace(true);
            org.jdom.Document documentDefaultValues = builderConfig.build(inDefaultValues);
			
			Element defaultValues = documentDefaultValues.getRootElement();
			
			String defaultValue_Link_bandwidth="", defaultValue_Link_queue="", defaultValue_Link_delay="",defaultValue_Link_linkType="";
			
			List listOfFormats = defaultValues.getChildren();
			Iterator ilistOfFormats = listOfFormats.iterator();
			while(ilistOfFormats.hasNext()){
				Element currentChildOfDefaultValues = (Element)ilistOfFormats.next();
				
				if(currentChildOfDefaultValues.toString().equals("[Element: <format/>]")) {
					
					if(currentChildOfDefaultValues.getAttributeValue("name").equals("TCL")){
						
						List listOfDefaultValuesOfFormat = currentChildOfDefaultValues.getChildren();
						Iterator ilistOfDefaultValuesOfFormat = listOfDefaultValuesOfFormat.iterator();
						while(ilistOfDefaultValuesOfFormat.hasNext()){
							Element currentChildOfFormat = (Element)ilistOfDefaultValuesOfFormat.next();
							
							if(currentChildOfFormat.toString().equals("[Element: <link/>]")){
								
								List listOfChildOfNode = currentChildOfFormat.getChildren();
								Iterator ilistOfChildOfNode = listOfChildOfNode.iterator();
								while(ilistOfChildOfNode.hasNext()){
									Element currentUnit = (Element)ilistOfChildOfNode.next();
									
									if(currentUnit.toString().equals("[Element: <unit/>]")){
										
										if(currentUnit.getAttributeValue("type").equals("bandwidth")){
											defaultValue_Link_bandwidth=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("queue")){
											defaultValue_Link_queue=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("delay")){
											defaultValue_Link_delay=currentUnit.getAttributeValue("value");
										}											
										if(currentUnit.getAttributeValue("type").equals("linkType")){
											defaultValue_Link_linkType=currentUnit.getAttributeValue("value");
										}	
									}
								}
							}
						}
					}
				}
			}				
			/*************************************************************************************************************************************************/
			
			org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
			builder.setIgnoringElementContentWhitespace(true);
			org.jdom.Document document = builder.build(ftp);
			
			domain = document.getRootElement();
			
			/* Test to know domain's sons */
			boolean BoolInformation = false;
			boolean BoolIGP = false;
			
			List domainChildren = domain.getChildren();
			Iterator idomainChildren = domainChildren.iterator();
			while(idomainChildren.hasNext()) {
				Element currentChild = (Element)idomainChildren.next();
				if(currentChild.toString().equals("[Element: <information/>]")) { BoolInformation=true; }
				if(currentChild.toString().equals("[Element: <igp/>]")) { BoolIGP=true; }
				
			}
			
			topology = domain.getChild("topology");
			nodes = topology.getChild("nodes");
			links = topology.getChild("links");
			
			
			bw.write("set ns [new Simulator]");
			bw.newLine();
			bw.newLine();
			bw.write("#Node declaration");
			bw.newLine();
			
			/* Topology */
			/* Node */
			List node = nodes.getChildren();
			Iterator iNode = node.iterator();
			while(iNode.hasNext()) {
				Element current = (Element)iNode.next();
				String nodeId = current.getAttributeValue("id");
				bw.write("set "+nodeId+" [$ns node]");
				bw.newLine();
			}
			
			bw.newLine();
			bw.write("#Edge declaration");
			bw.newLine();
			
			/* Links */
			List link = links.getChildren();
			Iterator iLink = link.iterator();
			while(iLink.hasNext()) {
				Element current = (Element)iLink.next();
				String linkId = current.getAttributeValue("id");
				String sourceNode = current.getChild("source").getAttributeValue("node");
				String targetNode = current.getChild("target").getAttributeValue("node");
				
				String bandwidthRes = "";
				
				boolean BoolBand = false;
				boolean BoolDelay = false;
				boolean BoolQueue = false;
				boolean BoolLinkType = false;
				
				List linkfils = current.getChildren();
				Iterator iLinkfils = linkfils.iterator();
				while(iLinkfils.hasNext()) {
					Element cur = (Element)iLinkfils.next();
					//System.out.println("Child : "+cur.toString());
					if(cur.toString().equals("[Element: <bandwidth/>]")) { BoolBand=true; }
					if(cur.toString().equals("[Element: <delay/>]")) { BoolDelay=true; }
					if(cur.toString().equals("[Element: <queue/>]")) { BoolQueue=true; }
					if(cur.toString().equals("[Element: <linkType/>]")) { BoolLinkType=true; }
				}
				
				if(BoolBand==true) {
					long bandwidth = Long.parseLong(current.getChildText("bandwidth"));
					if((bandwidth/1000000)<1000) {
						long div = (bandwidth/1000000);
						bandwidthRes = div+"Mb";
					}
					else if (((bandwidth/1000000000)<100) && ((bandwidth/1000000)>1)) {
						long div = (bandwidth/1000000000);
						bandwidthRes = div+"Gb";
					}
				}
				else {
					bandwidthRes = defaultValue_Link_bandwidth;
				}
				
				String delay = "";
				if(BoolDelay==true) {
					delay = current.getChildText("delay");
					if(delay.equals("undef")) {
						delay = "10ms";
					}
					else {
						delay = delay+"ms";
					}
				}
				else {
					delay = defaultValue_Link_delay;
				}
				
				String queue = "";
				if(BoolQueue==true) {
					queue = current.getChildText("queue");
				}
				else {
					queue = defaultValue_Link_queue;
				}
				
				String linkType = "";
				if(BoolLinkType==true) {
					List attrLink = current.getChild("linkType").getAttributes();
					Iterator iAttr = attrLink.iterator();
					while(iAttr.hasNext()) {
						Attribute attrCurrent = (Attribute)iAttr.next();
						//System.out.println("Attributes : "+attrCurrent.toString());
						if(attrCurrent.toString().contains("[Attribute: <type1")) { linkType = current.getChild("linkType").getAttributeValue("type1"); }
						else {linkType = defaultValue_Link_linkType;}
					}
				}
				else {
					linkType = defaultValue_Link_linkType;
				}
				
				bw.write("$ns "+linkType+" $"+sourceNode+" $"+targetNode+" "+bandwidthRes+" "+delay+" "+queue);
				bw.newLine();
				
			}
			/* End Links */
			/* End Topology */
			
			
			/* IGP */
			/* Links */
			try {
				if(BoolIGP==true) {
					igp = domain.getChild("igp");
					igpLinks = igp.getChild("links");
					
					List igplink = igpLinks.getChildren();
					Iterator iigpLink = igplink.iterator();
					
					bw.newLine();
					bw.write("#IGP costs");
					bw.newLine();
					
					while(iigpLink.hasNext()) {
						Element current = (Element)iigpLink.next();
						String linkId = current.getAttributeValue("id");
						String sourceNode = current.getChild("source").getAttributeValue("node");
						String targetNode = current.getChild("target").getAttributeValue("node");
						String cost = current.getChildText("cost");
						
						bw.write("$ns cost $"+sourceNode+" $"+targetNode+" "+cost);
						bw.newLine();
						
					}
				}
			} catch(Exception e){
				e.printStackTrace();
			}
			/* End Links */
			/* End IGP */
			
			bw.newLine();
			
			bw.close();
			fw.close();
			result.add("ParserToTCL","Export succeeded");
			
		} catch (Exception e) {
			e.printStackTrace();
			result.add("ParserToTCL","Export had problems "+e);
		}
		
	}
}
